Skip to content

Release 0.11.2 - #56

Merged
FlorianRappl merged 16 commits into
mainfrom
devel
Nov 12, 2026
Merged

FlorianRappl merged 16 commits into
mainfrom
devel

Conversation

@FlorianRappl

Copy link
Copy Markdown
Contributor

Types of Changes

Prerequisites

Please make sure you can check the following two boxes:

  • I have read the CONTRIBUTING document
  • My code follows the code style of this project

Contribution Type

What types of changes does your code introduce? Put an x in all the boxes that apply:

  • Bug fix (non-breaking change which fixes an issue, please reference the issue id)
  • New feature (non-breaking change which adds functionality, make sure to open an associated issue first)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • My change requires a change to the documentation
  • I have updated the documentation accordingly
  • I have added tests to cover my changes
  • All new and existing tests passed

Description

This pull request introduces version 0.11.2 of AngleSharp.Renderer, focusing on significant performance improvements, correctness fixes, and expanded test coverage. The main highlights are optimizations for deeply nested pages, more efficient handling of flex and table layouts, reduced memory allocations, and bug fixes for text node handling. It also adds new and improved tests to ensure robustness and correctness of these changes.

These changes collectively make AngleSharp.Renderer faster, more reliable, and better tested, especially for complex and deeply nested web pages.

FlorianRappl and others added 16 commits November 10, 2026 12:20
Layout, intrinsic sizing, inline collection and margin collapsing recurse per
nesting level with large frames, so 45 nested divs (18 tables, 28 flex
containers) overflowed a 1.5 MB stack and ended the process. Each of these
walks now checks RuntimeHelpers.TryEnsureSufficientExecutionStack and leaves
the rest of the subtree out instead.
Without the stack guard the test host crashes with a stack overflow.
A trial layout is laid out on its own, so the same inputs give the same
result within one render. Nested tables and inline-blocks trial-laid out
every level again for each level above it, doubling the work per level
(20 nested tables took 16 s, 22 over a minute). Trials inside a trial,
the ones the layout around them repeats, are now kept per element with
their inputs (style map, width, inherited style, measuring mode) for the
render, not inside a line-clamped box; incremental rendering drops them
on every change.
Without the trial cache, 6 nested tables take 63 trial layouts and 12 take
4095 (2^depth - 1).
Laid out only a few times, the layout stays in the first JIT tier, whose
frames are large: 12 nested inline-blocks overflowed the test thread's
stack on macOS. With tiered compilation off, devel and the trial cache
need the same stack.
Each of their levels lays out the levels below it twice, so up to the
depth the stack allows the test never completed in CI. They come back
once the nested trial layouts are reused (#54).
Reuse nested trial layouts within a render
…again

With the nested trial layouts reused (#54), they render in well under a
second.
Leave out deep subtrees instead of overflowing the stack
@FlorianRappl FlorianRappl added this to the v0.11.2 milestone Nov 12, 2026
@FlorianRappl
FlorianRappl merged commit a655134 into main Nov 12, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants